From b418a191ab6dd48738407c93f64824af6e61a748 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 22 Jun 2010 16:37:53 +0100 Subject: [PATCH] python/xc: [PATCH 3/3] add flask capabilities in python xc bindings The flask library is small, and putting everything in libxenctrl make relying on flask functionalities in libxl easier. libflask is left for compatibility purpose, but should be considered deprecated, and remove in the near future. all flask_ symbols are now xc_flask_ symbols in libxenctrl. Signed-off-by: Vincent Hanquez --- tools/python/xen/lowlevel/xc/xc.c | 251 ++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 13704249b5..6e9d3e1ac5 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -34,6 +34,8 @@ #define PKG "xen.lowlevel.xc" #define CLS "xc" +#define FLASK_CTX_LEN 1024 + static PyObject *xc_error_obj, *zero; typedef struct { @@ -2078,6 +2080,202 @@ static PyObject *pyxc_cpupool_freeinfo(XcObject *self) return cpumap_to_cpulist(cpumap); } +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *ctx; + char *buf; + uint32_t len; + uint32_t sid; + int ret; + + static char *kwd_list[] = { "context", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, + &ctx) ) + return NULL; + + len = strlen(ctx); + + buf = malloc(len); + if (!buf) { + errno = -ENOMEM; + PyErr_SetFromErrno(xc_error_obj); + } + + memcpy(buf, ctx, len); + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + free(buf); + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid); + + xc_interface_close(xc_handle); + + free(buf); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return PyInt_FromLong(sid); +} + +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + uint32_t sid; + char ctx[FLASK_CTX_LEN]; + uint32_t ctx_len = FLASK_CTX_LEN; + int ret; + + static char *kwd_list[] = { "sid", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &sid) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_sid_to_context(xc_handle, sid, ctx, ctx_len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("s", ctx, ctx_len); +} + +static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds) +{ + xc_interface *xc_handle; + char *policy; + uint32_t len; + int ret; + + static char *kwd_list[] = { "policy", NULL }; + + if( !PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwd_list, &policy, &len) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_load(xc_handle, policy, len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_getenforce(PyObject *self) +{ + xc_interface *xc_handle; + int ret; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_getenforce(xc_handle); + + xc_interface_close(xc_handle); + + if ( ret < 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_setenforce(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + int mode; + int ret; + + static char *kwd_list[] = { "mode", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &mode) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_setenforce(xc_handle, mode); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_access(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *tcon, *scon; + uint16_t tclass; + uint32_t req, allowed, decided, auditallow, auditdeny, seqno; + int ret; + + static char *kwd_list[] = { "src_context", "tar_context", + "tar_class", "req_permissions", + "decided", "auditallow","auditdeny", + "seqno", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ssil|llll", kwd_list, + &scon, &tcon, &tclass, &req, &decided, + &auditallow, &auditdeny, &seqno) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided, + &auditallow, &auditdeny, &seqno); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i",ret); +} + static PyMethodDef pyxc_methods[] = { { "domain_create", (PyCFunction)pyxc_domain_create, @@ -2677,6 +2875,59 @@ static PyMethodDef pyxc_methods[] = { "Get info about cpus not in any cpupool.\n" "Returns: [list]: List of CPUs\n" }, + { "flask_context_to_sid", + (PyCFunction)pyflask_context_to_sid, + METH_KEYWORDS, "\n" + "Convert a context string to a dynamic SID.\n" + " context [str]: String specifying context to be converted\n" + "Returns: [int]: Numeric SID on success; -1 on error.\n" }, + + { "flask_sid_to_context", + (PyCFunction)pyflask_sid_to_context, + METH_KEYWORDS, "\n" + "Convert a dynamic SID to context string.\n" + " context [int]: SID to be converted\n" + "Returns: [str]: Numeric SID on success; -1 on error.\n" }, + + { "flask_load", + (PyCFunction)pyflask_load, + METH_KEYWORDS, "\n" + "Loads a policy into the hypervisor.\n" + " policy [str]: policy to be load\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_getenforce", + (PyCFunction)pyflask_getenforce, + METH_NOARGS, "\n" + "Returns the current mode of the Flask XSM module.\n" + "Returns: [int]: 0 for permissive; 1 for enforcing; -1 on failure.\n" }, + + { "flask_setenforce", + (PyCFunction)pyflask_setenforce, + METH_KEYWORDS, "\n" + "Modifies the current mode for the Flask XSM module.\n" + " mode [int]: mode to change to\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_access", + (PyCFunction)pyflask_access, + METH_KEYWORDS, "\n" + "Returns whether a source context has access to target context based on \ + class and permissions requested.\n" + " scon [str]: source context\n" + " tcon [str]: target context\n" + " tclass [int]: target security class\n" + " req [int] requested permissions\n" + " allowed [int] permissions allow for the target class between the source \ + and target context\n" + " decided [int] the permissions that were returned in the allowed \ + parameter\n" + " auditallow [int] permissions set to audit on allow\n" + " auditdeny [int] permissions set to audit on deny\n" + " seqno [int] not used\n" + "Returns: [int]: 0 on all permission granted; -1 if any permissions are \ + denied\n" }, + { NULL, NULL, 0, NULL } }; -- 2.30.2